home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
CheapText.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-21
|
5KB
|
263 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "CheapText.h"
#include "Class.h"
#include "RegularExp.h"
#include "Port.h"
#include "Error.h"
#include "Math.h"
const int cInitCap= 16;
//---- CheapText ------------------------------------------------------------
NewMetaImpl(CheapText,Text, (T(next), T(size), TV(cont,next)));
CheapText::CheapText(int s, Font *fd)
{
size= Math::Max(cInitCap, s);
cont= new byte[size];
next= 0;
Init(next, fd);
}
CheapText::CheapText(byte *t, int len, Font *fd)
{
int ll= len;
if (ll == -1)
next= strlen((char*)t);
else
next= len;
size= Math::Max(cInitCap,(next / 5 + 1)* 6); // give some initial free space
cont= new byte[size];
MemCpy(cont, t, next);
Init(next, fd);
}
void CheapText::Init(int, Font *fd)
{
SetFont(fd);
SetDefTab(fd->Width((byte*)" ",8));
Terminate();
}
void CheapText::InitNew()
{
Text::InitNew();
Init(0, gSysFont);
}
CheapText::~CheapText()
{
SafeDelete(cont);
}
void CheapText::Terminate()
{
if (IsTerminated())
return;
byte null= '\0';
InsertBytes(&null, 1, Size(), Size());
}
void CheapText::ReplaceRange(int from, int to, Text *src, int sfrom, int sto)
{
CheapText *ct;
byte *buf= 0;
if (!CheckRange(End(), from, to))
Error("PasteText", "out of range");
if (!src->IsKindOf(CheapText)) { // convert
int s= sto-sfrom;
buf= new byte[s+1];
src->CopyInStr(buf, s+1, sfrom, sto);
sto= sto-sfrom;
sfrom= 0;
ct= new CheapText(buf, s);
} else
ct= (CheapText*)src;
InsertBytes(ct->cont+sfrom, sto-sfrom, from, to);
if (buf) {
delete buf;
delete ct;
}
}
Text *CheapText::MakeScratchText(byte *buf, int len)
{
if (buf)
return new CheapText(buf, len);
return new CheapText(len);
}
void CheapText::CopyInStr(byte *str, int size, int from, int to)
{
if (!CheckRange(next, from, to) || str == 0)
return;
register int l= Math::Min(to, from+size-1) - from;
MemCpy(str, &cont[from], l);
str[l]= '\0';
}
void CheapText::AddChar(int at, byte b)
{
InsertBytes(&b, 1, at, at);
}
byte *CheapText::GetLineAccess(byte**, int from, int to)
{
if (!CheckRange(next, from, to))
return 0;
return &cont[from];
}
int CheapText::Search(RegularExp *rex, int *nMatched, int start, int range,
bool dir)
{
if (dir == cSearchForward)
return rex->SearchForward((char*)cont, nMatched, start, End(), range, 0);
return rex->SearchBackward((char*)cont, nMatched, start, End(), range, 0);
}
void CheapText::InsertBytes(byte *c, int n, int from, int to)
{
int shift= n - (to - from);
if (HighWaterMark(shift))
Expand(GrowSize(size+shift));
if (shift < 0)
MemCpy(&cont[to+shift], &cont[to], next-to);
else if (shift > 0)
MemCpy(&cont[from+shift], &cont[from], next-from);
//---- insert pasted text
MemCpy(&cont[from], c, n);
next += shift;
if (LowWaterMark())
Expand(size/2);
}
byte& CheapText::operator[](int i)
{
if (!CheckRange(next, i, i))
i= size-1;
return cont[i];
}
int CheapText::Size()
{
return next;
}
void CheapText::Expand(int newSize)
{
if (newSize < Size()) // texts never shrinks
return;
cont= (byte*) Realloc(cont, newSize);
next= Math::Min(newSize, next);
size= newSize;
}
TextIter *CheapText::MakeIterator(int from, int to)
{
return new CheapTextIter(this,from,to);
}
OStream& CheapText::PrintOn(OStream &s)
{
Text::PrintOn(s);
return s.PrintString(cont, next);
}
IStream& CheapText::ReadFrom(IStream& s)
{
SafeDelete(cont);
Text::ReadFrom(s);
s.ReadString(&cont, &size);
next= size;
return s;
}
OStream& CheapText::PrintOnAsPureText(OStream &s)
{
s.write(cont, End());
return s;
}
IStream& CheapText::ReadFromAsPureText(IStream& s, long sizeHint)
{
char ch;
if (sizeHint > 0) {
int delta= (int)(sizeHint - size); // !!!
if (delta > 0)
Expand(delta + 50);
}
next= 0;
while (s.get(ch)) {
if (HighWaterMark(1))
Expand(GrowSize(size+1));
cont[next++]= ch;
}
if (!s.eof())
Error("ReadFromAsPureText", "something strange happened");
Terminate();
return s;
}
//----- class CheapTextIter ---------------------------------------------
CheapTextIter::CheapTextIter(Text *s, int from, int to) : TextIter(s, from, to)
{
if (!s->IsKindOf(CheapText))
Error("CheapTextIter::CheapTextIter", "CheapText expected");
font= s->GetFont();
}
int CheapTextIter::operator()(int *w, LineDesc* ld)
{
CheapText *ctp= (CheapText*)ct;
if (ld)
ld->FromFont(font);
unget= ce;
if (ce == upto)
return cEOT;
int ch= ctp->cont[ce++];
if (w)
*w= font->Width(ch);
return ch;
}
int CheapTextIter::Token(int *w,LineDesc* ld)
{
CheapText *ctp= (CheapText*)ct;
unget= ce;
*w= 0;
if (ld)
ld->FromFont(font);
if (ce >= upto)
return cEOT;
register int ch= ctp->CharAt(ce);
if (Iswordwrap(ch)) {
*w= font->Width(ch);
ce++;
return (ch);
}
while (ce < upto && !Iswordwrap(ctp->CharAt(ce))) {
ch= ctp->CharAt(ce++);
*w+= font->Width(ch);
}
return (ch);
}